From 167b02743b6cd4d7e5a880f28f451a23d0a753cc Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 1 Mar 2007 12:14:53 +0000 Subject: [PATCH] x86: No need to take full reference when doing mmu_update on a foreign domain. Also fix a pre-existing race setting PGT_pinned versus clearing it during domain_kill(). Signed-off-by: Keir Fraser --- xen/arch/x86/mm.c | 19 +++++++++++-------- xen/include/xen/sched.h | 9 +++++++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 10f5a86b4d..d7cd042086 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1853,7 +1853,7 @@ static void process_deferred_ops(void) if ( unlikely(info->foreign != NULL) ) { - put_domain(info->foreign); + rcu_unlock_domain(info->foreign); info->foreign = NULL; } } @@ -1885,8 +1885,7 @@ static int set_foreigndom(domid_t domid) switch ( domid ) { case DOMID_IO: - get_knownalive_domain(dom_io); - info->foreign = dom_io; + info->foreign = rcu_lock_domain(dom_io); break; default: MEM_LOG("Dom %u cannot set foreign dom", d->domain_id); @@ -1896,18 +1895,16 @@ static int set_foreigndom(domid_t domid) } else { - info->foreign = e = get_domain_by_id(domid); + info->foreign = e = rcu_lock_domain_by_id(domid); if ( e == NULL ) { switch ( domid ) { case DOMID_XEN: - get_knownalive_domain(dom_xen); - info->foreign = dom_xen; + info->foreign = rcu_lock_domain(dom_xen); break; case DOMID_IO: - get_knownalive_domain(dom_io); - info->foreign = dom_io; + info->foreign = rcu_lock_domain(dom_io); break; default: MEM_LOG("Unknown domain '%u'", domid); @@ -2043,6 +2040,12 @@ int do_mmuext_op( /* A page is dirtied when its pin status is set. */ mark_dirty(d, mfn); + /* We can race domain destruction (domain_relinquish_resources). */ + if ( unlikely(this_cpu(percpu_mm_info).foreign != NULL) && + test_bit(_DOMF_dying, &FOREIGNDOM->domain_flags) && + test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) ) + put_page_and_type(page); + break; case MMUEXT_UNPIN_TABLE: diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index cbfb67a9e7..0ab2874129 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -292,10 +292,15 @@ static inline void rcu_unlock_domain(struct domain *d) rcu_read_unlock(&domlist_read_lock); } +static inline struct domain *rcu_lock_domain(struct domain *d) +{ + rcu_read_lock(d); + return d; +} + static inline struct domain *rcu_lock_current_domain(void) { - rcu_read_lock(&domlist_read_lock); - return current->domain; + return rcu_lock_domain(current->domain); } struct domain *get_domain_by_id(domid_t dom); -- 2.30.2